﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Linq.Dynamic.Core;

namespace YYQ.Core
{
    public static class QueryFilterExtensions
    {
        /// <summary>
        /// 动态筛选
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query">IQueryable</param>
        /// <param name="filterRules"></param>
        /// <param name="alias">表别名</param>
        /// <returns></returns>
        public static IQueryable<T> ApplyFilters<T>(this IQueryable<T> query, string filterRules)
        {
            if (string.IsNullOrEmpty(filterRules)) return query;

            var filters = JsonSerializer.Deserialize<List<DataFilter>>(filterRules);

            if (filters == null || filters.Count == 0)
                return query;

            return query.ApplyFilters(filters);
        }

        /// <summary>
        /// 处理Easyui字段过滤
        /// </summary>
        /// <param name="filters"></param>
        /// <param name="a"></param>
        /// <returns></returns>
        public static IQueryable<T> ApplyFilters<T>(this IQueryable<T> query, List<DataFilter> filters)
        {
            if (filters == null || filters.Count == 0)
                return query;

            //type=GUID
            var stringGuidList = from f in filters where f.type != null && f.type == "GUID" select f;
            foreach (var i in stringGuidList)
            {
                query = query.Where($"{i.field} == @0",i.value);
            }
            //type=string
            var stringList = from f in filters where f.type != null && f.type == "string" select f;
            foreach (var i in stringList)
            {
                query = query.Where($"{i.field}.Contains(@0)", i.value);
            }
            //type=stringlist
            var stringlistList = from f in filters where f.type != null && f.type == "stringlist" select f;
            foreach (var i in stringlistList)
            {
                var valuelist = i.value.Split(',').ToList();

                query = query.Where($"@0.Contains(i.field)", valuelist);
            }
            //type=boolean
            var booleanList = from f in filters where f.type != null && f.type == "boolean" select f;
            foreach (var i in booleanList)
            {
                query = query.Where($"{i.field}=", i.value);
            }
            //type=numeric
            var numericList = from f in filters where f.type != null && f.type == "numeric" group f by f.field into g select g;
            foreach (var i in numericList)
            {
                var iiStr = i.Aggregate(string.Empty, (current, ii) => current + (ii.field + ii.op + ii.value + " and "));

                query = query.Where(iiStr.Substring(0, iiStr.Length - 4));
            }
            //type=date
            var dateList = from f in filters where f.type != null && f.type == "datebox" group f by f.field into g select g;
            foreach (var i in dateList)
            {
                var iiStr = i.Aggregate(string.Empty, (current, ii) => current + (ii.field  + ii.op + "DateTime'" + Convert.ToDateTime(ii.value).ToString("yyyy-MM-dd HH:mm") + "' " + " and "));
                
                query = query.Where(iiStr.Substring(0, iiStr.Length - 4));
            }
            //type=list  :"1,2"
            var listList = from f in filters where f.type != null && f.type == "list" select f;
            foreach (var i in listList)
            {
                if (i.value == "NULL")
                    query = query.Where($"{i.field} == null");
                else
                    query = query.Where($"{i.field}.Contains(@0)", i.value.Split(',').ToList());
            }

            return query;
        }
    }
}
